--[[
***********************************************************************************************************************
*
* Copyright (C) 2019 Richtek Technology Corp. All rights reserved
*
* This program is richtek proprietary: It can only be used by authorized 
* customer's products, and do not disturb it in source code.
*
* If you have any doubts, please contact us
*
***********************************************************************************************************************
*
* Richtek Lua Environment Script for RTBB SVI2 module 
* 
* Revision : 001 (2019/02/25)
* Author : Tsunghan Tsai
*
* Note :
*	This file must be loaded after the init_base.lua
*
***************
* Global :
*
* @ g_SVI2_fCurrentMax		(default : 100 mA)
*		'Telemetry, SVT Packet' Current Max 
*
***************
* Enum :
*
* typedef enum
* {
*	eRTExtSVI2Freq20MHz = 1,
*	eRTExtSVI2Freq15MHz = 2,
*	eRTExtSVI2Freq10MHz = 4,
*	eRTExtSVI2Freq25MHz = 8,
*	eRTExtSVI2Freq30MHz = 16,
*	eRTExtSVI2Freq40MHz = 32,
* } ERTExtSVI2Frequency;
*
* typedef enum
* {
*	eRTExtSVI2BootVID1_1 = 0,
*	eRTExtSVI2BootVID1_0 = 1,
*	eRTExtSVI2BootVID0_9 = 2,
*	eRTExtSVI2BootVID0_8 = 3,
* } ERTSVI2BootVID;
*
***************
* Function :
*
***********************************************************************************************************************
* function init_module_SVI2(eFrequency)
*
*	SVI2 module initialize 
*
*	Parameter :
*	@ eFrequency : Refer to enum ERTExtSVI2Frequency
*
*
***********************************************************************************************************************
* function SVI2PowerUp()
*
* 	Set power up of the SVI2 device.
*
*	Parameter :
*	@ eBootVIDCode : Refer to enum ERTSVI2BootVID
*	
*	Return Value :
*	# bResult: The reuslt of RTBB operation.
*
*
***********************************************************************************************************************
* function SVI2PowerDown()
*
*	Set power down of the SVI2 device.
*
*	Return Value :
*	# bResult: The reuslt of RTBB operation.
*
*
***********************************************************************************************************************
* function SVI2IsPowerUp()
*
*	Check power status of the SVI2 device.
*
*	Return Value :
*	# bPowerUp: Power Status is Up(true) or Down (false)
*	# bResult: The reuslt of RTBB operation.
*
*
***********************************************************************************************************************
* function SVI2SendCmd(nCmd)
* function SVI2SendCmd(VDD_SEL, VDDNB_SEL, PSI0_L, PSI1_L, VID_CODE, TFN, LoadLineSlopeTrim, OffsetTrim) 
* 
*	Send SVD data packet command to SVI2 device.
*
*	Parameter :
*	@ nCmd : 
*		SVD data packet for SVI2 device VDD_SEL, VDDNB_SEL, PSI0_L, PSI1_L, 
*			VID_CODE, TFN, LoadLineSlopeTrim, OffsetTrim setting.
*
*	@ VDD_SEL, VDDNB_SEL, PSI0_L, PSI1_L, VID_CODE, TFN, LoadLineSlopeTrim, OffsetTrim:
*		Please refer to SVI2 document
*
*	Return Value :
*	# bResult: The reuslt of RTBB operation.
*
*
***********************************************************************************************************************
* function SVI2RecvData()
*
*	Receive data from SVI2 device
*
*	Return Value :
*	# tlbData :  A tlb to the buffer that receives the data from the SVI2 bus
*	# nCount :  Data length received from the SVI2 bus.
*	# bResult: The reuslt of RTBB operation.
*
*
***********************************************************************************************************************
* function SVI2ExtractSVTData(svtData, bTrace)
*
*	Extract SVT data which was received  from SVI2RecvData()
*
*	@ svtData : Telemetry, SVT Packet
*	@ bTrace : Trace Extract Result (dbgprintf)
*
*	Return Value :
*	# svt :  
*		0 : Telemetry Packet belongs to the VDD domain and telemetry is in V&I mode.
*		1 : Telemetry Packet belongs to then VDDNB domain and telemetry is in V&I mode.
*		2 : VOTF Complete, a stop immediately follows these two bits during the next SVC high period
*		3 : Telemetry Packet is voltage only
*	
*	# data0 : depend on svt field
*	# data1 : depned on svt field 
*
*	Remark : 
*		1, If the data type is current, then the range is determined by SVI2SetCurrentMax()
*		2, Voltage Unit : mV, Current Unit : mA
*
*********************************************************************************************************************** 
* function SVI2SetCurrentMax(imax)
*
*	Set 'Telemetry, SVT Packet' Current Max 
*
*	@ imax : SVT packet Current Max
*
*********************************************************************************************************************** 
* function SVI2GetCurrentMax()
*
*	Get 'Telemetry, SVT Packet' Current Max 
*
*	# imax : SVT packet Current Max
*
--]]

-----------------------------------------------------------------------------------------------------------------------
-- Global Variable Init 
-----------------------------------------------------------------------------------------------------------------------

g_SVI2_fCurrentMax = 100	-- 100 mA

-----------------------------------------------------------------------------------------------------------------------
-- Power Control
-----------------------------------------------------------------------------------------------------------------------

function SVI2PowerUp(nBootVIDCode)
	local nResult = RTBB_EXTSVI2_SVI2PowerUp(
		g_hBridgeBoard, nBootVIDCode)

		
	dbgprintf("SVI2PowerUp(%d)\n", nBootVIDCode)
	bRet = resultMsg("RTBB_EXTSVI2_SVI2PowerUp", nResult)
	
	return bRet
end

function SVI2PowerDown()
	local nResult = RTBB_EXTSVI2_SVI2PowerDown(g_hBridgeBoard)

	dbgprintf("SVI2PowerDown\n")
	bRet = resultMsg("RTBB_EXTSVI2_SVI2PowerDown", nResult)
	
	return bRet
end

function SVI2IsPowerUp()
	local bPowerUp
	local bResult = true
	local nResult = RTBB_EXTSVI2_SVI2IsPowerUp(g_hBridgeBoard)

	resultMsg("SVI2IsPowerUp",nResult)
	
	if (nResult == 1) then
		bPowerUp = true
		dbgprintf("SVI2IsPowerUp? Yes\n")
	else 
		if (nResult == 0) then
			bPowerUp = false
			dbgprintf("SVI2IsPowerUp? No\n")
		else
			bResult = false
		end
	end
	
	return bPowerUp, bResult
end

-----------------------------------------------------------------------------------------------------------------------
-- Write
-----------------------------------------------------------------------------------------------------------------------

function __SVI2SendCmd(VDD_SEL, VDDNB_SEL, PSI0_L, PSI1_L, VID_CODE, TFN, LoadLineSlopeTrim, OffsetTrim) 
	
	local nResult = RTBB_EXTSVI2_SVI2SendCmd(g_hBridgeBoard, VDD_SEL, VDDNB_SEL, 
		PSI0_L, PSI1_L, VID_CODE, TFN, LoadLineSlopeTrim, OffsetTrim)

	dbgprintf("SVI2SendCmd (%x %x %x %x %x %x %x %x)\n", VDD_SEL, VDDNB_SEL, 
		PSI0_L, PSI1_L, VID_CODE, TFN, LoadLineSlopeTrim, OffsetTrim)		
		
	bRet = resultMsg("RTBB_EXTSVI2_SVI2SendCmd", nResult)
	
	return bRet	
	
end

function __SVI2SendCmdEx(nCmd)
	local nResult = RTBB_EXTSVI2_SVI2SendCmdEx(g_hBridgeBoard, nCmd)

	dbgprintf("SVI2SendCmd (0x%x)\n", nCmd);
	bRet = resultMsg("RTBB_EXTSVI2_SVI2SendCmdEx", nResult)
	
	return bRet
end

function SVI2SendCmd(v1, v2, v3, v4, v5, v6, v7, v8)

	if (v2 == nil) then
		return __SVI2SendCmdEx(v1)
	end
	
	return __SVI2SendCmd(v1, v2, v3, v4, v5, v6, v7, v8);
end

-----------------------------------------------------------------------------------------------------------------------
-- Read
-----------------------------------------------------------------------------------------------------------------------

function SVI2RecvData() 

	local data = {}

	local nResult, nCount = RTBB_EXTSVI2_SVI2RecvData(g_hBridgeBoard, data)

	bRet = resultMsg( "RTBB_EXTSVI2_SVI2RecvData", nResult )

	dbgprintf("SVI2RecvData (Count=%d): ", nCount)
	for i=1,nCount,1 do
		dbgprintf("0x%x,",data[i])
	end
	dbgprintf("\n")
	
	return data, nCount, bRet;
end

function SVI2SetCurrentMax(imax)
	g_SVI2_fCurrentMax = imax
	dbgprintf("SVI2SetCurrentMax(%.2f mA)\n", imax)
end

function SVI2GetCurrentMax()
	return g_SVI2_fCurrentMax
end

function SVI2ExtractSVTData(svtData, bTrace)

	function SVI2Val2Voltage(val)	
		return 3150 + (-val*6.25);
	end 

	function SVI2Val2Current(val)
		return g_SVI2_fCurrentMax*val/255;
	end

	function svttrace()
	end
	
	if ((bTrace ~= nil) and bTrace) then
		svttrace = dbgprintf
	end
	
	local svt = bit.band(bit.ror(svtData, 18), 0x03)	
	local raw0 = bit.band(bit.ror(svtData, 9), 0x1ff)
	local raw1 = bit.band(svtData, 0x1ff)
	
	svttrace("SVI2ExtractSVTData (0x%x)\n", svtData);
	
	if svt == 2 then 
		svttrace("Received VOTF\n");
		return
	else if svt == 0 then
		data0 = SVI2Val2Voltage(raw0)
		data1 = SVI2Val2Current(raw1)
		
		svttrace("TelemetryPacket belongs to the VDD domain and telemetry is in V&I mode\n");
		svttrace("VDD Voltage: %.2f mV\n", data0);
		svttrace("VDD Current: %.2f mA\n", data1);
		
	else if svt == 1 then
		data0 = SVI2Val2Voltage(raw0)
		data1 = SVI2Val2Current(raw1)	
		
		svttrace("TelemetryPacket belongs to the VDDNB domain and telemetry is in V&I mode\n");
		svttrace("VDDNB Voltage: %.2f mV\n", data0);
		svttrace("VDDNB Current: %.2f mA\n", data1);
		
	else if svt == 3 then
		data0 = SVI2Val2Voltage(raw0)
		data1 = SVI2Val2Voltage(raw1)	
	
		svttrace("TelemetryPacket in voltage only\n");
		svttrace("VDD Voltage: %.2f mV\n", data0);
		svttrace("VDDNB Voltage: %.2f mV\n", data1);		
	end end end end	
	
	svttrace("\n");
	return svt, data0, data1
end	

-----------------------------------------------------------------------------------------------------------------------
-- Module Init 
-----------------------------------------------------------------------------------------------------------------------

function init_module_SVI2(eFrequency)

	nResult = RTBB_EXTSVI2_SVI2SetFrequency(g_hBridgeBoard, eFrequency)
	if (nResult ~= RT_BB_SUCCESS) then
		return false 
	end

	return true
end
